﻿/*
 
 * Date: 2/14/2011
 * Time: 1:05 PM
 * 
 * 
 */
using System;
using System.Diagnostics;
using System.Drawing;
using System.Linq.Expressions;
using System.Threading;
using System.Windows.Forms;
using System.ServiceProcess;
using System.Collections.Generic;
using System.Configuration;
using Utility.ServiceQuickChange;

namespace ServiceQuickChange
{
    public sealed class NotificationIcon
    {
        private NotifyIcon _Icon;
        
        private MenuItem _ServiceMenu = null;
        
        private string _FriendlyErrorMessage ="No errors!";
        private bool _CanInitialize = true;
        
        private string _serviceName=null;
        
        private ServiceCommander _ServiceCommander = null;
       
        private System.Windows.Forms.Timer _Timer = new  System.Windows.Forms.Timer();
        
        private string _previous_status = "";
        
        private Dictionary<string, Icon> _IconStates = new Dictionary<string, Icon> ();
        
        private void LoadIconStates()
        {
            
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NotificationIcon));
            resources.IgnoreCase =true;
            _IconStates.Add("Stopped",  (Icon)resources.GetObject("IconStopped.ico"));
            _IconStates.Add("Unknown",  (Icon)resources.GetObject("IconUnknown.ico"));
            _IconStates.Add("Running",  (Icon)resources.GetObject("IconRunning.ico"));
            _IconStates.Add("Error",  (Icon)resources.GetObject("IconError.ico"));
            
           
            
        }
        public void LoadConfiguration()
        {
              ServiceConfigurationSectionSettings config = null;
              _CanInitialize = _CanInitialize && true;
              try {
              config   = ConfigurationManager.GetSection("serviceName")
                  as ServiceConfigurationSectionSettings;
            
              _serviceName = config.Name;
              
              } catch(Exception ex)
              {
                  _serviceName ="Invalid Configuration File";
                  _FriendlyErrorMessage = "Invalid Configuration File";
                  _CanInitialize = false;
              }
              

        }

        public void SaveConfiguration()
        {
            //todo
        }
        #region Initialize icon and menu
        public NotificationIcon()
        {
            
           LoadIconStates();
            _Icon = new NotifyIcon();
            _Icon.Icon = _IconStates["Unknown"];
            _Icon.Visible =true;
           
            LoadConfiguration();  
            
            _Icon.ContextMenu = new ContextMenu(InitialMenu());
            _Icon.ContextMenu.Popup +=  new EventHandler(this.menuOnPopup ) ;
            
            if (_CanInitialize )
            {
                try {
                _ServiceCommander = new ServiceCommander(_serviceName,_ServiceMenu);
                }
                catch( Exception ex)
                {
                    _FriendlyErrorMessage = "INVALID service (" + _serviceName + ")";
                 
                    _CanInitialize = false ;
              
                }
            }
            
            if (_CanInitialize) //normal startup
            {
            _Timer.Interval = 1000;
            _Timer.Tick += Timer_NormalPeriodicUpdate;
            _Timer.Enabled = true;
            _Timer.Start();
            } else // controlled shutdown with error message
            {
             _Timer.Interval = 500;
            _Timer.Tick += Timer_AbnormalShutdown;
            _Timer.Enabled = true;
            _Timer.Start(); 
                
            }
                
        }
        private MenuItem[] InitialMenu()
        {
            
            _ServiceMenu = new MenuItem("New Item"  , menuService1Click);
            _ServiceMenu.MenuItems.Add (new MenuItem("Toggle", menuToggleClicked ));
            
            MenuItem[] menu = new MenuItem[]  {
                new MenuItem("About", menuAboutClick)
                ,new MenuItem("Exit", menuExitClick)
                ,_ServiceMenu
                
            };
         return menu;
        }
        #endregion
        
        #region Main - Program entry point
        /// <summary>Program entry point.</summary>
        /// <param name="args">Command Line Arguments</param>
        [STAThread]
        public static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            
           
            bool isFirstInstance;
            // Please use a unique name for the mutex to prevent conflicts with other programs
            using (Mutex mtx = new Mutex(true, "ServiceQuickChange", out isFirstInstance)) {
                if (isFirstInstance) {
                    
                    NotificationIcon notificationIcon = new NotificationIcon();
                    notificationIcon._Icon.Visible = true;
                   
                    Application.Run();
                    notificationIcon._Icon.Dispose();
                } else {
                    //There can be only one instance of this program
                    
                }
            } // releases the Mutex
        }

        #endregion
        #region Event Handlers

            
        private void menuOnPopup(object sender, EventArgs e)
        {
            
            _ServiceMenu.Text =  _ServiceCommander.GetServiceMenuName();
            
            string status = _ServiceCommander.GetStatus();
            
            string toggleCommandText = _ServiceCommander.GetToggleCommandText();
            
            _ServiceMenu.MenuItems[0].Text =toggleCommandText;
            
        }    
            
        private void menuService1Click(object sender, EventArgs e)
        {
            MessageBox.Show("menuService1Click");
        }
         private void menuAboutClick(object sender, EventArgs e)
        {
             frmAbout.ShowMe();
        }
        
         private void menuToggleClicked(object sender, EventArgs e)
        {
            string newCommand = _ServiceMenu.MenuItems[0].Text;
            try 
            {
            _ServiceCommander.ApplyServiceCommandState(newCommand);
            } catch(Exception ex)
            {
                 _Icon.Icon = _IconStates["Error"];
                _Icon.ShowBalloonTip( 2000,"Problem", _serviceName + " is not commandable - please check configuration, service is disabled.",ToolTipIcon.Warning );
            }
            Timer_NormalPeriodicUpdate(null, null);
           
        }
        
        private void menuExitClick(object sender, EventArgs e)
        {
            Application.Exit();
        }
        
        
        
       
        private void Timer_AbnormalShutdown(object sender, EventArgs e)
        {
            _Timer.Enabled = false;
            _Icon.Icon = _IconStates["Error"];
            _Icon.Visible =true;
            _Icon.ShowBalloonTip(2000,"Problem",_FriendlyErrorMessage + "\nProgram will now terminate." ,ToolTipIcon.Warning );
            System.Threading.Thread.Sleep(3000);
            
            Application.Exit();
        }
        private void Timer_NormalPeriodicUpdate(object sender, EventArgs e)
        {
            
           _Timer.Enabled = false;
            
                string status = _ServiceCommander.GetStatus();
                bool change = (_previous_status != status);
                _previous_status = status;
               
                
                
                if (change) 
                {
               
                    if (status =="Running")
                    {
                        _Icon.Icon = _IconStates["Running"];
                       
                    }else if (status == "Stopped")
                    {
                        _Icon.Icon = _IconStates["Stopped"];
                    }
                    else {
                        _Icon.Icon = _IconStates["Unknown"];
                    }
                }
            _Icon.Visible =true;  
           
            _Timer.Enabled = true;
           
        }
        #endregion
    }
}